<template>
  <a-popover v-model:open="visible" placement="bottomLeft" trigger="click">
    <template #title>
      <a-form-item>
        <a-radio-group @change="updateSelectIconArray" v-model:value="iconStyle">
          <a-radio-button value="outlined">线框风格</a-radio-button>
          <a-radio-button value="filled">实底风格</a-radio-button>
          <a-radio-button value="twoTone">双色风格</a-radio-button>
        </a-radio-group>
      </a-form-item>
      <a-form-item>
        <a-input-search v-model:value="searchValue" placeholder="输入英文关键词进行搜索" @change="updateSelectIconArray" />
      </a-form-item>
    </template>

    <template #content>
      <a-flex class="icon-box" :gap="5" wrap="wrap">
        <div v-for="item in iconLoopArray" :key="item" @click="handleClick(item)" class="icon-content">
          <component :is="($antIcons as any)[item]" />
        </div>
        <a-button v-show="showMoreIndex > 0" type="link" @click="showMore" class="button">
          点击展开更多图标（因图标较多，可能会卡一小会）
        </a-button>
      </a-flex>
    </template>

    <slot name="iconSelect"></slot>
  </a-popover>
</template>

<script setup lang="ts">
  import * as VueIcon from '@ant-design/icons-vue';
  import { endsWith, slice } from 'lodash-es';
  import { computed, ref, watch } from 'vue';

  //线框风格图标数组
  const outlinedIconArray = Object.keys(VueIcon).filter((key) => endsWith(key.toLowerCase(), 'outlined'));
  //实底风格图标数组
  const filledIconArray = Object.keys(VueIcon).filter((key) => endsWith(key.toLowerCase(), 'filled'));
  //双色风格图标数组
  const twoToneIconArray = Object.keys(VueIcon).filter((key) => endsWith(key.toLowerCase(), 'twotone'));

  // ------------ 显示/隐藏 ------------
  const visible = ref(false);

  // ------------ 展开更多 ------------
  const SHOW_MORE_LENGTH = 35;
  const showMoreIndex = ref(SHOW_MORE_LENGTH);
  function showMore() {
    showMoreIndex.value = -1;
  }

  // ------------ 图标展示与搜索 ------------

  const iconStyle = ref('outlined');
  const selectIconArray = ref([...outlinedIconArray]);

  const iconLoopArray = computed(() => {
    return slice(selectIconArray.value, 0, showMoreIndex.value);
  });

  watch(iconStyle, () => {
    updateSelectIconArray();
  });

  const searchValue = ref('');
  function updateSelectIconArray() {
    let tempArray = null;
    if (iconStyle.value === 'outlined') {
      tempArray = outlinedIconArray;
    } else if (iconStyle.value === 'filled') {
      tempArray = filledIconArray;
    } else {
      tempArray = twoToneIconArray;
    }
    if (!searchValue.value) {
      selectIconArray.value = tempArray;
    } else {
      selectIconArray.value = tempArray.filter((key) => key.toLowerCase().includes(searchValue.value.toLowerCase()));
    }

    if (selectIconArray.value.length > SHOW_MORE_LENGTH) {
      showMoreIndex.value = SHOW_MORE_LENGTH;
    }
  }

  // ------------ 对外抛出选择图标事件 ------------
  const emit = defineEmits(['updateIcon']);
  function handleClick(icon: string) {
    visible.value = false;
    emit('updateIcon', icon);
  }
</script>

<style scoped lang="less">
  .icon-box {
    overflow: auto;
    font-size: 20px;
    width: 410px;
    height: 300px;
    display: flex;

    .icon-content {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 45px;
      height: 40px;
      border-radius: 6px;
      border: 1px solid #ccc;
      cursor: pointer;
    }
    .icon-content:hover {
      background: #1890ff;
    }

    .button {
      width: 100%;
      text-align: start;
    }
  }
</style>
